package uk.ac.ebi.das.uniprot.image.util;


import org.apache.log4j.Logger;
import uk.ac.ebi.das.uniprot.image.exception.ImageException;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Properties;

/**
 * Created by IntelliJ IDEA.
 * User: ljgarcia
 * Date: 15-Feb-2011
 * Time: 14:10:57
 * Helper class to read configuration properties
 */

public class RetrievalHelper {
    private static Logger logger = Logger.getLogger(RetrievalHelper.class);
    private static Properties configProps = null;
    private static final String CONFIG_PROPERTIES_FILE = "/image.properties";
    private static final String DAS_REFERENCE_PROPERTY = "das.reference";
    private static final String GENERATED_IMAGES_DIR_PROPERTY = "generated.images.dir";
    private static final String IMAGE_WIDTH_PROPERTY = "image.width";
    private static final String IMAGE_STYLE_PROPERTY = "image.style";
    private static final String DAS_SOURCE_PROPERTY = "das.source";
    private static final String OPTION_RESPONSE_PROPERTY = "option.response";
    private static final String FEATURE_SOURCE = "feature.source.";
    private static final String FEATURE_SOURCE_DOMAIN = "feature.source.DOMAIN";
    private static final String FEATURE_DISPLAY = "feature.display.";

    private static void initPropertiesFile() {
        if (configProps == null) {
            try {
                configProps = new Properties();
                configProps.load(new FileInputStream(CONFIG_PROPERTIES_FILE));
            } catch (Exception e) {
                logger.info("Properties file could not be read, default properties will be used. ERROR: " + e.getMessage());
                configProps = new Properties();
                //reference source
                configProps.put(DAS_REFERENCE_PROPERTY, "http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot");
                //configProps.put(DAS_REFERENCE_PROPERTY, "http://wwwdev.ebi.ac.uk:21280/das-srv/uniprot/das/uniprot");

                //annotation sources
                configProps.put(DAS_SOURCE_PROPERTY, "http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot");
                //configProps.put(DAS_SOURCE_PROPERTY, "http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot,http://www.ebi.ac.uk/das-srv/interpro/das/InterPro-matches-overview");
                //configProps.put(DAS_SOURCE_PROPERTY, "http://wwwdev.ebi.ac.uk:21280/das-srv/uniprot/das/uniprot,http://www.ebi.ac.uk/das-srv/interpro/das/InterPro-matches-overview");

                //features by annotation source
                //configProps.put(FEATURE_SOURCE_DOMAIN, "http://www.ebi.ac.uk/das-srv/interpro/das/InterPro-matches-overview");

                //image width
                configProps.put(IMAGE_WIDTH_PROPERTY, "700");

                //image type (raphael/image)
                configProps.put(OPTION_RESPONSE_PROPERTY, "raphael");

                //style
                configProps.put(IMAGE_STYLE_PROPERTY, "nonOverlapping");

                //generated image directory
                configProps.put(GENERATED_IMAGES_DIR_PROPERTY, "generatedImages");

                //default features to be displayed
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.DOMAIN.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.CA_BIND.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.NP_BIND.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.DNA_BIND.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.INTRAMEM.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.TOPO_DOM.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.TRANSMEM.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.ZN_FING.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.PEPTIDE.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.PROPEP.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.SIGNAL.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.TRANSIT.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.ACT_SITE.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.METAL.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.CARBOHYD.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.LIPID.getType(), "true");
                configProps.put(FEATURE_DISPLAY + FeatureTypeConfig.MOD_RES.getType(), "true");
            }
        }
    }
    /**
     * Retrieves the uniprot.reference property
     * @return
     */
    public static String getDasReferenceURL() throws ImageException {
        initPropertiesFile();
        String serverURL = configProps.getProperty(DAS_REFERENCE_PROPERTY);
        if (serverURL != null) {
            return serverURL;
        } else {
            logger.error("The protein reference source URL has not been configured");
            throw new ImageException("The protein reference source URL has not been configured");
        }
    }

    /**
     * Retrieves the generated.images.dir property
     * @return
     */
    public static String getGeneratedImagesDir() throws ImageException {
        initPropertiesFile();
        String dir = configProps.getProperty(GENERATED_IMAGES_DIR_PROPERTY);
        if (dir != null) {
            return dir;
        } else {
            logger.error("The generated images directory has not been configured");
            throw new ImageException("The generated images directory has not been configured");
        }
    }

    /**
     * Retrieves the image.width property
     * @return
     */
    public static int getImageWidth() throws ImageException {
        initPropertiesFile();
        try {
            int width = Integer.parseInt(configProps.getProperty(IMAGE_WIDTH_PROPERTY));
            if (width != 0) {
                return width;
            } else {
                logger.error("The image default width has not been configured");
                throw new ImageException("The image default width has not been configured");
            }
        } catch (Exception e) {
            logger.info("The image default width has not been configured as an integer, default value will be 640");
            return 640;
        }
    }

    /**
     * Retrieves the das.source property
     * @return
     */
    public static String getImageStyle() {
        initPropertiesFile();
        String style = configProps.getProperty(IMAGE_STYLE_PROPERTY);
        if (style != null) {
            return style;
        } else {
            logger.error("The default style has not been configured, 'centered' will be used");
            return "centered";
        }
    }

    /**
     * Retrieves the das.source property
     * @return
     */
    public static String getDasSource() throws ImageException {
        initPropertiesFile();
        String dir = configProps.getProperty(DAS_SOURCE_PROPERTY);
        if (dir != null) {
            //return dir.split(",");
            return dir;
        } else {
            logger.error("The DAS default sources have not been configured");
            throw new ImageException("The DAS default sources have not been configured");
        }
    }

    /**
     * Retrieves the option.response property
     * @return
     */
    public static String getOptionResponse() {
        initPropertiesFile();
        String dir = configProps.getProperty(OPTION_RESPONSE_PROPERTY);
        if (dir != null) {
            return dir;
        } else {
            logger.error("The default response option has not been configured, 'raphael' will be used");
            return "raphael";
        }
    }

    /**
     * Retrieves the feature.source.XXX property
     * @param type Feature type to look into the properties
     * @return
     */
    public static String getFeatureSource(FeatureTypeConfig type) {
        initPropertiesFile();
        String source = configProps.getProperty(FEATURE_SOURCE + type.getType());
        if (source != null) {
            return source;
        } else {
            //logger.debug("The default source to be used for " + type.getType() + " has not been configured, features from all annotation sources will be retrieved for this type");
            return null;
        }
    }

    /**
     * Retrieves the feature.source.XXX property
     * @param type Feature type to look into the properties
     * @return
     */
    public static boolean getFeatureDisplay(FeatureTypeConfig type) {
        initPropertiesFile();
        String display = configProps.getProperty(FEATURE_DISPLAY + type.getType());
        if (display != null) {
            try {
                return Boolean.parseBoolean(display);
            } catch (Exception e) {
                return false;
            }
        } else {
            //logger.debug("The default display to be used for " + type.getType() + " has not been configured, this feature will not be displayed");
            return false;
        }
    }

    /**
     * Retrieves all feature.source.XXX properties corresponding to feature types as specified in FeatureTypeConfig.
     * @return
     */
    public static HashMap<String, String> getAllFeatureSource() {
        HashMap<String, String> featureSourceMap = new HashMap<String, String>();
        initPropertiesFile();
        for (FeatureTypeConfig type: FeatureTypeConfig.values()) {
            String source = configProps.getProperty(FEATURE_SOURCE + type.getType());
            if (source != null) {
                featureSourceMap.put(type.getType(), source);
            } else {
                //logger.debug("The default source to be used for " + type.getType() + " has not been configured, features from all annotation sources will be retrieved for this type");
            }
        }
        return featureSourceMap;
    }
}

